文章同步發表至 medium
昨天提到我們想要做到重新渲染 markers 這件事情。從功能上來看,初始化地圖和新增 markers 的確是兩件事,所以我的思路會是把這兩件事情分開來,一開始就初始化,有資料之後才去渲染 markers。
為了做到這件事情,我們需要進行一些調整:
const app = Vue.createApp({
data(){
return{
// 新增一個物件來接初始化之後的地圖
map: null
}
},
methods:{
initMap(){
// 把初始化後的物件丟到 Vue 裡
this.map = L.map('map');
this.map.setView([24.175339, 120.648586], 19);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
},
resetMarkers(data){
// 建立 markers
let markers = L.markerClusterGroup();
data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
this.map.addLayer(markers);
},
getScenicSpots(){
axios({
method: 'get',
url: './api/ScenicSpot'
}).then(res => {
// 改成呼叫 resetMarkers()
this.resetMarkers(res.data);
}).catch(err => {
console.log(err);
})
},
searchScenicByCounty(){
Swal.fire({
// ...
}).then((result) => {
if (result.isConfirmed) {
axios({
method: 'get',
url: `./api/ScenicSpot/${result.value}`
}).then(res => {
// 改成呼叫 resetMarkers()
this.resetMarkers(res.data);
}).catch(err => {
console.log(err);
})
}
})
},
},
mounted(){
// 先初始化地圖
this.initMap();
this.getScenicSpots();
}
});
app.mount('#app');
來看看我們修正的第一版結果:
初始化和取得所有景點看起來是正常的,接下來我們試試景點查詢的功能:
操作起來沒問題,但因為我們沒有先把前一次新增上去的 markers 移除,所以新增進去的會和舊有的一起顯示,但這很明顯不是 Feature,是 Bug。
我的思路還是很簡單,給他一個物件存起來,如果這個物件不是空的,那就把它整包移除:
const app = Vue.createApp({
data(){
return{
map: null,
// 新增一個物件來接 markers
oldMarkers: null
}
},
methods:{
initMap(){
// ...
},
resetMarkers(data){
// 如果舊有的 markers 不是空的,就移除
if (this.oldMarkers !== null) this.map.removeLayer(this.oldMarkers);
let markers = L.markerClusterGroup();
data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
this.map.addLayer(markers);
},
getScenicSpots(){
// ...
},
searchScenicByCounty(){
// ...
},
},
mounted(){
// ...
}
});
app.mount('#app');
有新增移除之後的結果:
原本的 markers 都被移除了,只剩下我們查詢的縣市的景點們。